package cn.com.bluemoon.daps.sync.core.sync.meta;

import cn.com.bluemoon.daps.model.entity.DapDataModelSubordinateKey;
import cn.com.bluemoon.daps.model.entity.DapDataModelTable;
import cn.com.bluemoon.daps.model.entity.DapDataModelTableField;
import cn.com.bluemoon.metadata.common.enums.IndexMethodEnum;
import cn.com.bluemoon.metadata.common.enums.IndexTypeEnum;
import cn.com.bluemoon.metadata.common.enums.JudgeEnum;
import cn.com.bluemoon.metadata.common.enums.SortingEnum;
import cn.com.bluemoon.metadata.inter.dto.out.ColumnInfoVO;
import cn.com.bluemoon.metadata.inter.dto.out.FieldInfoVO;
import cn.com.bluemoon.metadata.inter.dto.out.SqlIndexInfoVO;
import cn.com.bluemoon.metadata.inter.dto.out.TableInfoVO;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Jarod.Kong
 * @date 2021/6/4 13:24
 */
@Slf4j
public class MetadataConverter {
    // 默认给个空格的字符串
    private static final String COMMENT_NULL_TO_DEFAULT = "该注释缺失，请补充";

    public static class Table {
        public static DapDataModelTable mgToLocal(TableInfoVO tableInfoVO) {
            DapDataModelTable table = new DapDataModelTable();
//                table.setBusinessDesc(tableInfoVO.getComment());
            table.setEngName(tableInfoVO.getName());
            table.setName(StrUtil.emptyToDefault(tableInfoVO.getComment(), COMMENT_NULL_TO_DEFAULT));
            return table;
        }
    }

    public static class Field {
        public static DapDataModelTableField mgToLocal(ColumnInfoVO columnInfoVO) {
            DapDataModelTableField field = new DapDataModelTableField();
            JudgeEnum isAutoIncrement = columnInfoVO.getIsAutoIncrement();
            if (JudgeEnum.YES.equals(isAutoIncrement)) {
                if (columnInfoVO.getInitialValue() != null) {
                    long initValue = 0;
                    try {
                        initValue = Long.parseLong(columnInfoVO.getInitialValue());
                    } catch (NumberFormatException e) {
                        log.error("获取元数据提供的初始值转为long失败，取默认值0", e);
                    }
                    field.setAutoIncrDefaultValue(initValue);
                }
                field.setAutoIncrement(1);
            } else {
                field.setAutoIncrement(0);
            }
            field.setComment(StrUtil.emptyToDefault(columnInfoVO.getComment(), COMMENT_NULL_TO_DEFAULT));
            field.setDataType(columnInfoVO.getSqlSimpleType());
            // 针对timestamp情况的缺省值进行合并 2021年8月2日
            String defaultVal = columnInfoVO.getColumnDefault();
            boolean isTimestampDataType = ("timestamp".equalsIgnoreCase(columnInfoVO.getSqlSimpleType()) || "datetime".equalsIgnoreCase(columnInfoVO.getSqlSimpleType()));
            if (isTimestampDataType &&
                    "current_timestamp".equalsIgnoreCase(columnInfoVO.getColumnDefault()) &&
                    "on update current_timestamp".equalsIgnoreCase(columnInfoVO.getExtra())) {
                defaultVal = columnInfoVO.getColumnDefault() + " " + columnInfoVO.getExtra();
                log.debug("针对timestamp/datetime字段类型进行特殊处理，默认值{}->{}", columnInfoVO.getColumnDefault(), defaultVal);
            }
            field.setDefaultValue(defaultVal);
            field.setFieldName(columnInfoVO.getName());
            field.setLength(columnInfoVO.getLength());
            field.setDecimalLength(columnInfoVO.getScale());
            field.setNotNull(JudgeEnum.YES.equals(columnInfoVO.getIsNullable()) ? 0 : 1);
            field.setPrimaryKey(JudgeEnum.YES.equals(columnInfoVO.getIsPrimary()) ? 1 : 0);
            field.setFieldRank(columnInfoVO.getSeq());
            field.setUnSigned(JudgeEnum.YES.equals(columnInfoVO.getUnsigned()) ? 1 : 0);
            field.setZeroFill(JudgeEnum.YES.equals(columnInfoVO.getZerofill()) ? 1 : 0);
            field.setTableName(columnInfoVO.getTableName());
            return field;
        }
    }

    public static class Index {
        public static DapDataModelSubordinateKey mgToLocal(SqlIndexInfoVO indexInfoVO) {
            // 2021/5/31 有问题 => 过滤掉primary的，模型中不维护
            if (IndexTypeEnum.PRIMARY.equals(indexInfoVO.getIdxType())) {
                return null;
            }
            DapDataModelSubordinateKey index = new DapDataModelSubordinateKey();
            index.setKeyChinName(StrUtil.nullToDefault(indexInfoVO.getComment(), COMMENT_NULL_TO_DEFAULT));
            // key method
            if (IndexMethodEnum.BTREE.equals(indexInfoVO.getIdxMethod())) {
                index.setKeyMethod(2);
            } else if (IndexMethodEnum.HASH.equals(indexInfoVO.getIdxMethod())) {
                index.setKeyMethod(3);
            } else {
                index.setKeyMethod(DapDataModelSubordinateKey.KEY_METHOD_DEFAULT_KEY);
            }
            index.setKeyName(indexInfoVO.getName());
            if (IndexTypeEnum.FULLTEXT.equals(indexInfoVO.getIdxType())) {
                index.setKeyType(4);
            } else if (IndexTypeEnum.UNIQUE.equals(indexInfoVO.getIdxType())) {
                index.setKeyType(3);
            } else if (IndexTypeEnum.NORMAL.equals(indexInfoVO.getIdxType())) {
                index.setKeyType(2);
            } else {
                index.setKeyType(DapDataModelSubordinateKey.KEY_TYPE_DEFAULT_KEY);
            }
            List<FieldInfoVO> fields = indexInfoVO.getFields();
            List<DapDataModelTableField> dbFields = fields.stream().map(f -> {
                DapDataModelTableField field = new DapDataModelTableField();
                field.setFieldName(f.getName());
                field.setSorting(SortingEnum.ASC.equals(f.getSorting()) ? 1 : 0);
                field.setFieldRank(f.getSqlIndex());
                return field;
            }).collect(Collectors.toList());
//                index.setFieldIds();
            index.setIndexFields(dbFields);
            index.setFieldNames(dbFields.stream().map(DapDataModelTableField::getFieldName).collect(Collectors.joining(DapDataModelSubordinateKey.INDEX_FIELDIDS_CHAR)));
            index.setTableName(indexInfoVO.getTableName());
            return index;
        }
    }
}
